package com.jh.user.business.impl;

import cn.jh.common.exception.ServiceException;
import cn.jh.common.proxy.FreeQuickProxyService;
import cn.jh.common.utils.BeanUtil;
import cn.jh.common.utils.CommonConstants;
import cn.jh.common.utils.CommonsUtil;
import cn.jh.common.utils.DateUtil;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Table;
import com.jh.user.business.ChannelRateBusiness;
import com.jh.user.business.UserBusiness;
import com.jh.user.pojo.*;
import com.jh.user.pojo.enums.ChanPay;
import com.jh.user.pojo.enums.ChannelMerType;
import com.jh.user.pojo.enums.PayType;
import com.jh.user.pojo.enums.UserGrade;
import com.jh.user.pojo.freeQuick.PassageWayRegister;
import com.jh.user.repository.*;
import com.jh.user.repository.freeQuick.PassageWayRegisterRepository;
import com.jh.user.service.BrandRateRequest;
import com.jh.user.service.UserChannelRequest;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.jh.user.pojo.ChannelRate.getChannelRateFromUserChannelRequest;


@Service
public class ChannelRateBusinessImpl implements ChannelRateBusiness {

    private static final Logger LOG = LoggerFactory.getLogger(ChannelRateBusinessImpl.class);

	@Autowired
	private ChannelRateRepository channelRateRepository;

	@Autowired
	private ChannelRepository channelRepository;

	@Autowired
	private BrandRateRepository brandRateRepository;

	@Autowired
	private UserRepository userRepository;

	@Autowired
	private EntityManager em;

	@Autowired
	private JdbcTemplate jdbcTemplate;

	@Autowired
	private PassageWayRegisterRepository passageWayRegisterRepository;

	@Autowired
	private PassagewayBankinfoRepository passagewayBankinfoRepository;

	@Autowired
	private UserBusiness userBusiness;

	@Transactional
	@Override
	public Channel mergeChannel(Channel channel) {
		Channel result = channelRepository.save(channel);
		em.flush();
		return result;
	}

	public BrandRate queryBrandRate (String channelId,String payType,String grade){
		String sql = "select b.* from t_brand_rate b where b.channel_id = " + channelId + " and b.pay_type = " + payType +" and b.user_grade = " + grade;
		SqlRowSet set = jdbcTemplate.queryForRowSet(sql);
		BrandRate brand = new BrandRate();
		while (set.next()){
			brand.setRate(set.getBigDecimal("grade_rate"));
			brand.setBrandRate(set.getBigDecimal("brand_rate"));
			brand.setExtraFee(set.getBigDecimal("extra_fee"));
		}
		return brand;


	}

	@Override
	public Channel findChannelByTag(String channelTag) {
		return channelRepository.findChannelByTag(channelTag);
	}



	@Override
	public Channel findChannelById(long channelid) {

		Channel channel = new Channel();
		channel = channelRepository.findChannelById(channelid);
		return channel;
	}

	@Transactional
	@Override
	public ChannelRate mergeChannelRate(ChannelRate channelRate) {
		ChannelRate result = channelRateRepository.save(channelRate);
		em.flush();
		em.clear();
		return result;
	}

	@Override
	public ChannelRate findChannelRateByUserid(long userid, long channelid) {
		short payType = Short.parseShort("1");
		User user = userRepository.findUserById(userid);
		ChannelRate channelRate = channelRateRepository.findChannelRateByUserid(userid, user.getBrandId(), channelid,payType);
		return channelRate;
	}

	@Override
	public List<ChannelRate> findChannelRateByBrandid(long brandid, long channelid) {

		return channelRateRepository.findChannelRateByBrandid(brandid, channelid);
	}

	@Override
	public List<Channel> findAllChannel() {
		// TODO Auto-generated method stub
		return channelRepository.findAll();
	}
	/**
	 * 查询费率
	 * @param userId
	 * @param type
	 * @return
	 */

	public ChannelRate findAllChannelRate(long userId,long type,String channelType){
		//查询用户通道费率
		String sql = "select r.* from t_channel_rate r,t_user u,t_brand_rate b where u.grade = b.user_grade and u.id = r.user_id and r.status = 1 and u.id =  " + userId ;
		if(type > 0){
			sql+= " and b.pay_type = " + type;
		}
		if(StringUtils.isNotBlank(channelType)){
			sql += " and b.channel_id = " + channelType;
		}
		SqlRowSet set = jdbcTemplate.queryForRowSet(sql);
		ChannelRate channelRate = new ChannelRate();
		if(set == null){
			//查询用户角色汇率
			String sql1 = "select b.* from t_user u,t_brand_rate b where u.grade = b.user_grade and b.status = 1 and u.id = " + userId+" and b.pay_type = " + type +" and b.channel_id = " + channelType;
			set = jdbcTemplate.queryForRowSet(sql1);

		}
		while (set.next()){
			channelRate.setRate(set.getBigDecimal("rate"));
			channelRate.setExtraFee(set.getBigDecimal("extra_fee"));
		}
		return channelRate;
	}

	public List<Channel> findAll(String grade){
		//查询等级汇率
		String sql = "select t.*,b.rate,b.extra_fee as extraFee,t.min_extra_fee as minExtranFee,t.min_with_draw_fee as minWithDrawFee,b.pay_type as payType  from t_channel t,t_brand_rate b " +
				"where t.status = 1 and b.channel_id = t.channel_no and b.user_grade= " + grade ;
		List<Channel> result = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Channel.class));
		for(Channel channel : result){
			channel.setStartTime(channel.getStartTime().substring(0,channel.getStartTime().lastIndexOf(":")));
			channel.setEndTime(channel.getEndTime().substring(0,channel.getEndTime().lastIndexOf(":")));
		}
		return result;
	}

	public List<Channel> findRate(String grade,String payType){
		//查询等级汇率
		String sql = "select t.*,b.rate,b.extra_fee as extraFee,t.min_extra_fee as minExtranFee,t.min_with_draw_fee as minWithDrawFee,b.pay_type as payType  from t_channel t,t_brand_rate b " +
				"where t.status = 1 and b.channel_id = t.channel_no and b.user_grade= " + grade +" and b.pay_type = " + payType ;
		List<Channel> result = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Channel.class));
		for(Channel channel : result){
			channel.setStartTime(channel.getStartTime().substring(0,channel.getStartTime().lastIndexOf(":")));
			channel.setEndTime(channel.getEndTime().substring(0,channel.getEndTime().lastIndexOf(":")));
		}
		return result;
	}

	public List<Channel> findRateByChannel(String grade,String channelMerType){
		//查询等级汇率
		String sql = "select t.*,b.rate,b.extra_fee as extraFee,t.min_extra_fee as minExtranFee,t.min_with_draw_fee as minWithDrawFee,b.pay_type as payType  from t_channel t,t_brand_rate b " +
				"where t.status = 1 and b.channel_id = t.channel_no and b.user_grade= " + grade + " and t.channel_mer_type = " + channelMerType;
		List<Channel> result = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Channel.class));
		for(Channel channel : result){
			channel.setStartTime(channel.getStartTime().substring(0,channel.getStartTime().lastIndexOf(":")));
			channel.setEndTime(channel.getEndTime().substring(0,channel.getEndTime().lastIndexOf(":")));
		}
		return result;
	}

	/**
	 * 查询渠道
	 * @param userId
	 * @return
	 */
	public List<Channel> findAllChannel(long userId,long payType,long channelType,String amountMoney,String type){
		List<Channel> list = new ArrayList<>();
		try {
			//查询用户通道费率
			List<ChannelRate> lists = channelRateRepository.findChannelRateByUseridAndGrade(userId,"1");
			List<String> list1 = new ArrayList<>();
			for (ChannelRate channelRate : lists) {
				list1.add(String.valueOf(channelRate.getChannelId()));
			}
			HashSet h = new HashSet(list1);
			list1.clear();
			list1.addAll(h);

			List<Channel> channelList = channelRepository.findByChannelNoIn(list1);

			if (StringUtils.isNotBlank(type)){
				payType = Long.valueOf(type);
			}
			if(lists.size() > 0){
				for(ChannelRate rates :lists) {
					String channelId = String.valueOf(rates.getChannelId());
					for (Channel channel : channelList) {
						if (channel.getChannelNo().equals(channelId) && payType == rates.getPayType()) {
							channel.setRate(rates.getRate());
							channel.setExtraFee(rates.getExtraFee());
							channel.setPayType(String.valueOf(rates.getPayType()));
							channel.setChannelMerType(rates.getChannelMerType());
							list.add(channel);
							break;
						}
					}
				}
			} else {
				String brandRateSql = "SELECT * FROM t_brand_rate br WHERE br.STATUS = '1' AND " +
						"br.user_grade = ( SELECT u.grade FROM t_user u WHERE u.brand_id = '407' AND u.id = "+ userId +" )";
				List<BrandRate> brandRateList;
				try {
					brandRateList = jdbcTemplate.query(brandRateSql, new BeanPropertyRowMapper<>(BrandRate.class));
				} catch (Exception e) {
					LOG.info("userId = " + userId + " 根据userId，role_id查询t_brand_rate表公共费率为空");
					brandRateList = null;
				}
				if (null != brandRateList && brandRateList.size() > 0) {
					for (BrandRate br : brandRateList) {
						ChannelRate channelRate = new ChannelRate();
						channelRate.setChannelRateFromBrandRate(br);
						channelRate.setUserId(userId);
						try {
	//						channelRateRepository.saveAndFlush(channelRate);
							saveChannelRate(channelRate);
						} catch (RuntimeException e) {
							LOG.info("异常=======" + e.getMessage());
							e.printStackTrace();
						}
					}
				}
			}
			if(list.size() < 1 || list.isEmpty()){
				//查询用户角色汇率
				String sql1 = "select t.*,b.rate,b.extra_fee as extraFee ,b.pay_type as payType from t_user u,t_channel t,t_brand_rate b " +
						"where t.status = 1 and b.channel_id = t.channel_no and u.grade = b.user_grade and u.id = " + userId ;
				if(payType > 0){
					sql1 += " and b.pay_type = " + payType;
				}
				if(channelType > 0){
					sql1 += " and b.channel_id = " + channelType;
				}

				list = jdbcTemplate.query(sql1, new BeanPropertyRowMapper<>(Channel.class));

			}

			for(Channel channe : list){
				if(org.apache.commons.lang.StringUtils.isNotBlank(amountMoney)){
					BigDecimal money = new BigDecimal(amountMoney);
					//1在线收款
					if(type.equals("1")){
						//用户输入金额*费率
						BigDecimal rate = money.multiply(channe.getRate());

						//计算后的费率+手续费
						BigDecimal amount = rate.add(channe.getExtraFee());
						BigDecimal extraFee = channe.getExtraFee();
						BigDecimal fee = channe.getWithdrawFee();
						BigDecimal ex = fee.add(extraFee);
						//总手续费加上这次计算后的手续费
						BigDecimal fees = amount.add(fee);
						//把新的手续费赋值给总手续费
						channe.setWithdrawFee(fees.setScale(2,BigDecimal.ROUND_UP));
						channe.setExtraFee(ex);
						//获取输入金额
						BigDecimal amountMoney1 = new BigDecimal(amountMoney);
						if(amountMoney1 == null){
							amountMoney1 = new BigDecimal(0.00);
						}
						//用户输入金额减去计算后的总续费
						BigDecimal moneys = amountMoney1.subtract(channe.getWithdrawFee());
						//得到实际到账金额
						channe.setMoney(moneys.setScale(2,BigDecimal.ROUND_DOWN));
					}else{
						//用户输入金额*费率
						BigDecimal rate = money.multiply(channe.getRate());

						//计算后的费率+手续费
						BigDecimal amount = rate.add(channe.getExtraFee());
						BigDecimal fee = channe.getWithdrawFee();
						//总手续费加上这次计算后的手续费
						BigDecimal fees = amount.add(fee);
						//把新的手续费赋值给总手续费
						channe.setWithdrawFee(fees.setScale(2,BigDecimal.ROUND_UP));
						BigDecimal extraFee = channe.getExtraFee();
						BigDecimal ex = fee.add(extraFee);
						channe.setExtraFee(ex);
						//获取输入金额
						BigDecimal amountMoney1 = new BigDecimal(amountMoney);
						if(amountMoney1 == null){
							amountMoney1 = new BigDecimal(0.00);
						}
						//用户输入金额减去计算后的总续费
						BigDecimal moneys = amountMoney1.add(channe.getWithdrawFee());

						//得到实际到账金额
						channe.setMoney(moneys.setScale(2,BigDecimal.ROUND_UP));
					}
				}
	//			channe.setStartTime(channe.getStartTime().substring(0,channe.getStartTime().lastIndexOf(":")));
	//			channe.setEndTime(channe.getEndTime().substring(0,channe.getEndTime().lastIndexOf(":")));
				channe.setStartTime(channe.getStartTime().substring(0, 5));
				channe.setEndTime(channe.getEndTime().substring(0, 5));
			}

		} catch (RuntimeException e) {
			e.printStackTrace();
		}

		return list;

	}


	@Transactional
	public void saveChannelRate(ChannelRate channelRate) {
		channelRateRepository.saveAndFlush(channelRate);
//		em.merge(channelRate);
//		em.flush();
	}


	// 通过品牌Id查询通道
	@Override
	public List<Channel> findAllChannelByBrandid(long brandid){
		List<Channel> channels = new ArrayList<Channel>();
		List<BrandRate> brandRates = brandRateRepository.findBrandRateBybrandid(brandid);

		for (BrandRate brandRate : brandRates) {
			Channel channel = channelRepository.findChannelById(brandRate.getChannelId());
			if (channel != null) {
				if ("1".equals(channel.getStatus()))
					channel.setStatus(brandRate.getStatus());
				Channel nn = new Channel();
				nn = channel;
				nn.setRate(brandRate.getRate());
				nn.setExtraFee(brandRate.getExtraFee());
				//nn.setWithdrawFee(brandRate.getWithdrawFee());
				channels.add(nn);
			}
		}

		return channels;
	}

	@Override
	public List<ChannelRate> findChannelRates() {
		return channelRateRepository.findAll();
	}

	// 根据ChannelNo查询通道
	@Override
	public List<Channel> findChannelByChannelNo(String channelNo) {
		return channelRepository.findChannelByChannelNo(channelNo);
	}

	@Transactional
	@Override
	public void updChannelRateBybrandidAndChannelidanduserId(BigDecimal minrate, long brandid, long channelid,
															 long userid) {
		channelRateRepository.updChannelRateBybrandidAndChannelidanduserId(minrate, brandid, channelid, userid);

	}

	@Override
	public Channel findByChannelId(long channelId) {
		return channelRepository.findById(channelId);
	}

	@Override
	public List<ChannelRate> findChannelRateListByUserId(long userId) {
		return channelRateRepository.findChannelRateListByUserid(userId);
	}

	@Override
	public void updateChannelByChannelIdAndPayType(long channelId, Short payType, BigDecimal gradeRate) {
		channelRateRepository.updateChannelByChannelIdAndPayType(channelId, payType, gradeRate);
	}

	@Override
	public List<UserChannelRate> findUserChannelRate(Long userId) {
		User user = userRepository.findUserById(userId);
		// 用户等级
		UserGrade userGrade = user == null ? null : user.getUserGrade();
		if (user == null || userGrade == null) {
			return ImmutableList.of();
		}
		// 查询所有通道信息
		List<Channel> channelList = channelRepository.findAll();
		List<Long> channelIds = channelList.stream().map(Channel::getId).collect(Collectors.toList());
		List<BrandRate> brandRateList = brandRateRepository.findBrandRate(user.getBrandId(), channelIds);
		Table<Long, PayType, BrandRate> brandRateTable = HashBasedTable.create();
		Table<Long, PayType, BrandRate> maxBrandRateTable = HashBasedTable.create();
		for (BrandRate br: brandRateList) {
			if (br.getUserGrade() == userGrade) {
				brandRateTable.put(br.getChannelId(), br.ofPayType(), br);
			}
			if (br.getUserGrade() == UserGrade.PARTNER) {
				maxBrandRateTable.put(br.getChannelId(), br.ofPayType(), br);
			}
		}
		// 查询指定用户的通道信息
		List<ChannelRate> channelRateList = channelRateRepository.findByUserId(userId);
		Table<Long, PayType, ChannelRate> channelRateTable = HashBasedTable.create();
		for (ChannelRate channelRate: channelRateList) {
			channelRateTable.put(channelRate.getChannelId(), channelRate.ofPayType(), channelRate);
		}
		ChannelRate channelRate;
		List<UserChannelRate> result = Lists.newArrayList();
		for (Channel channel: channelList) {
			if (!Objects.equals(channel.getStatus(), "1")) continue;

			for (PayType payType: PayType.values()) {
				UserChannelRate userChannelRate = UserChannelRate.init(user, channel);
				channelRate = channelRateTable.get(channel.getId(), payType);
				if (channelRate == null) {
					// 需要去查公共费率BrandRate
					BrandRate brandRate = brandRateTable.get(channel.getId(), payType);
					if (brandRate == null) continue;
					userChannelRate.supply(brandRate.getBrandId(), brandRate.getPayType(),
							brandRate.getRate(), brandRate.getExtraFee(), brandRate.getGradeRate(),brandRate.getChannelMerType());
				} else {
					userChannelRate.supply(channelRate.getBrandId(), channelRate.getPayType(),
							channelRate.getRate(), channelRate.getExtraFee(), channelRate.getGradeRate(),channelRate.getChannelMerType());
				}
				BrandRate limitBrandRate = maxBrandRateTable.get(channel.getId(), payType);
				userChannelRate.limit(limitBrandRate);
				result.add(userChannelRate);
			}
		}
		return result;
	}

	@Transactional
	@Override
	public ChannelRate updateUserChannelRate(UserChannelRequest ucr) throws ServiceException {
		User user = userRepository.findUserById(ucr.getUserId());
		if (user == null) {
			throw new ServiceException("用户信息不存在");
		}

		PayType payType = ucr.getPayType();
		Channel channel = channelRepository.findChannelChannelNo(ucr.getChannelNo());
		if (channel == null) {
			throw new ServiceException("通道信息不存在");
		}
//		ChannelMerType channelMerType = ucr.getChannelMerType();

		// 设置的费率必须大于等于当前通道+用户最高等级的费率
		BrandRate maxBrandRate = brandRateRepository.findBrandRate(
				user.getBrandId(), ucr.getChannelId(), UserGrade.PARTNER, payType.getValue(),channel.getChannelMerType()
		);
		if (maxBrandRate == null) {
			throw new ServiceException("您的贴牌未设置初始费率");
		}

		if (ucr.getRate() != null && ucr.getRate().compareTo(maxBrandRate.getRate()) < 0) {
			throw new ServiceException("您设置的费率不能小于通道的最低费率"+ maxBrandRate.getRate());
		}

		UserChannelRequest ucRequest = ucr;

		ChannelRate channelRate = channelRateRepository.findChannelRate(ucr.getUserId(), user.getBrandId(), ucr.getChannelId(),
				payType.getValue(),channel.getChannelMerType());

		// 个人费率 >= 推广人费率 >= 贴牌费率 >= 平台费率 >= 上游通道费率
		// 修改后的个人费率
		BigDecimal rate = ucr.getRate();
		// 修改后的推广人费率
		BigDecimal gradeRate = ucr.getGradeRate();
		if (gradeRate.compareTo(rate) > 0) {
			throw new ServiceException("推广人费率不能大于个人费率！");
		}
		BigDecimal brandRate = maxBrandRate.getBrandRate();
		if (brandRate.compareTo(gradeRate) > 0) {
			throw new ServiceException("推荐人分润手续费必须大于贴牌费率！");
		}
		String sql="";
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String updateDate = sdf.format(date);

		if(channelRate == null){
			if (ucr.getRate() == null || ucr.getExtraFee() == null) {
				throw new ServiceException("用户通道费率初始必须传入费率和手续费");
			}

			channelRate = ChannelRate.initRate(user, payType.getValue(), ucr.getChannelId(),channel.getChannelMerType());
			if (ucr.getGradeRate() == null) {
				// 通道费率信息初始化时，如果用户没有传值gradeRate，则去取公共配置的值
				UserGrade userGrade = user.getUserGrade();
				if (userGrade == UserGrade.PARTNER) {
					ucr.setGradeRate(maxBrandRate.getGradeRate());
				} else {
					BrandRate currBrandRate = brandRateRepository.findBrandRate(
							user.getBrandId(), ucr.getChannelId(), userGrade, payType.getValue()
					);
					if (currBrandRate == null || currBrandRate.getGradeRate() == null) {
						throw new ServiceException("公共费率配置信息异常");
					}
					ucr.setGradeRate(currBrandRate.getGradeRate());
				}
			}

		//插入数据


			sql="INSERT INTO t_channel_rate (user_id, brand_id,channel_id, rate, extra_fee, grade_rate, status, pay_type, " +
					"update_time, create_time, brand_rate, channel_mer_type)" +
					" VALUES " +
					"(" ;
			sql+="'"+ucr.getUserId()+"','"+user.getBrandId()+"','"+ucr.getChannelId()+"','"+ucr.getRate()+"','"+ucr.getExtraFee()+"','"+ucr.getGradeRate()+"','"+1+"','"+payType.getValue()+"',";
			sql+="'"+updateDate+"','"+updateDate+"','"+new BigDecimal(channel.getCostRate())+"','"+channel.getChannelMerType()+"'";
			sql+=")";

		}else{
////			"update ChannelRate channelRate set channelRate.gradeRate = :gradeRate ,channelRate.rate = :rate,channelRate.extraFee = :extraFee,channelRate.brandRate = :brandRate where channelRate.payType = :payType and channelRate.channelId = :channelId and channelRate.channelMerType = :channelMerType
			sql = "update t_channel_rate set grade_rate= '" + ucr.getGradeRate() + "',rate='"+ucr.getRate()+"',extra_fee='"+ucr.getExtraFee()+"',brand_rate='"+new BigDecimal(channel.getCostRate())+"',update_time='"+updateDate+"' " +
					" where  pay_type = '"+payType.getValue()+"' and channel_id ='"+ucr.getChannelId()+"' and channel_mer_type = '"+channel.getChannelMerType()+"'";

		}
		jdbcTemplate.update(sql);
		channelRate.supply(ucr.getRate(), ucr.getExtraFee(), ucr.getGradeRate(),channel.getCostRate());

//		channelRateRepository.saveAndFlush(channelRate);

		Short type = ucr.getType();
		if (type == 1) {
			// 修改通道费率
			Long userId = ucr.getUserId();
			rate = ucr.getRate();
			gradeRate = ucr.getGradeRate();
			BigDecimal extraFee = ucr.getExtraFee();
			String channelId = String.valueOf(ucr.getChannelId());

			// 如果该用户是否注册上游通道，修改上游通道费率
			List<PassageWayRegister> registerList = new ArrayList<>();
			List<PassageWayRegister> passageWayRegisterList = passageWayRegisterRepository.queryByUserId(userId + "");
			if (null != passageWayRegisterList && passageWayRegisterList.size() > 0) {
				// 更新本地注册表费率
				for (PassageWayRegister passageWayRegister : passageWayRegisterList) {
					String channelProductCode = passageWayRegister.getChannelProductCode();
					if (channelId.equals(channelProductCode)) {
						passageWayRegister.setCreditRate(channelRate.getRate());
					}
					registerList.add(passageWayRegister);
					// 更新上游通道费率
					Map<String, String> resMap = FreeQuickProxyService.modifyMerchantFeeInfo(passageWayRegister.getRequestNo(),
							ChanPay.of(passageWayRegister.getChannelProductCode()).name(), CommonConstants.CREDIT_0, "TRADE", passageWayRegister.getCreditRate().toString(), "");
					String bizCode = resMap.get("bizCode");
					String bizMsg = resMap.get("bizMsg");
					String code = resMap.get("code");
					if (!"1".equals(bizCode) || !"200".equals(code)) {
						// 失败
						LOG.info("后台修改用户等级时修改上游通道费率结果：ChannelProductCode = {}, creditRate = {}, bizMsg = {}", ChanPay.of(passageWayRegister.getChannelProductCode()).name(), passageWayRegister.getCreditRate().toString(), bizMsg);
					}
				}
				passageWayRegisterRepository.save(registerList);
			}
		}
		return channelRate;
	}

	public Boolean modifyMerchantFeeInfo(UserChannelRequest ucRequest, ChannelRate channelRate, String existChannelRate) throws ServiceException {
		Boolean resFlag = false;
		ChannelRate oldChannelRate = getChannelRateFromUserChannelRequest(ucRequest);
		if ("1".equals(existChannelRate)) {
			// 存在
			userBusiness.upGradeToModifyMerchantFeeInfo(oldChannelRate, channelRate);
		}
		if ("0".equals(existChannelRate)) {
			// 不存在
			oldChannelRate.setRate(new BigDecimal("0.00"));
			oldChannelRate.setExtraFee(new BigDecimal("0"));
			userBusiness.upGradeToModifyMerchantFeeInfo(oldChannelRate, channelRate);
		}
		return resFlag;
	}

	/**
	 * 新增/修改渠道
	 * @param operating 0新增，1修改
	 * @param channelRequest
	 * @return
	 * @throws ServiceException
	 */
	@Override
	@Transactional
	public Map<String, Object> saveOfUpdateChannelInfo(String operating, ChannelRequest channelRequest, Channel channel) throws ServiceException {
		/* 1、校验非空 */

		Channel newChannel = null;
		if (CommonConstants.CHANNEL_ADD.equals(operating)) {
			/* 2、校验参数是否重复 */
			List<Channel> channelList = channelRepository.findAll();
			if (null != channelList && channelList.size() > 0) {
				for (Channel c : channelList) {
					if (channelRequest.getChannelNo().equals(c.getChannelNo())) {
						throw new ServiceException("添加失败，渠道商家标号已存在！");
					}
				}
			}

			/* 3、新增 */
//			Channel channel = new Channel();
			channel.addNewChannel(channelRequest);
			newChannel = channelRepository.save(channel);
			em.flush();
		}

		if (CommonConstants.CHANNEL_MODIFY.equals(operating)) {
			/* 4、修改 */
			String channelNo = channelRequest.getChannelNo();
			newChannel = channelRepository.findChannelChannelNo(channelNo);
			channel.setId(newChannel.getId());
			BeanUtil.copyPropertiesIgnoreNull(channel, newChannel);
			em.merge(newChannel);
			em.flush();
		}
		return newChannel.channelInfo();
	}

	@Override
	public List<Map<String, Object>> queryAllChannel() throws ServiceException {
		List<Map<String, Object>> resList = new ArrayList<>();
		List<Channel> channelList = channelRepository.findAll();
		if (null != channelList && channelList.size() > 0) {
			for (Channel channel : channelList) {
				Map<String, Object> channelInfo = channel.channelInfo();
				resList.add(channelInfo);
			}
		}
		return resList;
	}

	@Override
	public Map<String, Object> editBrandRate(long brandId, String channelNo, String payType, BigDecimal brandRate) throws ServiceException {
		if (brandRate.compareTo(BigDecimal.ZERO) <= 0 || brandRate.compareTo(BigDecimal.ONE) >= 0) {
			throw new ServiceException("贴牌费率必须大于0小于1！");
		}
		Pageable pageable = new PageRequest(0, 1, new Sort(Sort.Direction.ASC, "minrate"));
		Page<BrandRate> brandRatePage = brandRateRepository.queryBrandRateOrderByMinRate(brandId, pageable);
		List<BrandRate> content = brandRatePage.getContent();
		if (null != content && content.size() > 0) {
			BigDecimal minrate = content.get(0).getMinrate();
			if (brandRate.compareTo(minrate) < 0) {
				throw new ServiceException("贴牌费率不能小于最低费率！");
			}
		}

		List<BrandRate> brandRateList = brandRateRepository.findBrandRateBybrandid(brandId);
		for (BrandRate br : brandRateList) {
			br.setBrandRate(brandRate);
		}
		List<BrandRate> save = brandRateRepository.save(brandRateList);
		return CommonsUtil.returnSuccess("公共费率修改成功！", "");
	}

	@Override
	public BrandRate addBrandRate(BrandRateRequest brandRateRequest, BigDecimal brandrate) throws ServiceException {
		Long brandId = brandRateRequest.getBrandId();
		Long channelId = brandRateRequest.getChannelId();
		UserGrade userGrade = UserGrade.of(brandRateRequest.getGrade());
		Short payType = brandRateRequest.getType();
		BrandRate brandRate = brandRateRepository.queryBrandRateByFour(brandId, channelId, userGrade, payType);
		if (null != brandRate) {
			throw new ServiceException("已存在相同的公共费率信息！");
		}
		BrandRate one = BrandRate.createOne(brandRateRequest);
		one.setBrandRate(brandrate);
        BrandRate save = brandRateRepository.save(one);
        return save;
	}

	@Override
	@Transactional
	public void queryByUserId(long userId, long brandId, long grade) throws ServiceException {
		List<ChannelRate> channelRateList = channelRateRepository.queryByUserId(userId, brandId);
		List<BrandRate> brandRateList = brandRateRepository.queryByUserGrade(UserGrade.of(grade));
		List<ChannelRate> cRateList = new ArrayList<>();

		if (null == channelRateList || channelRateList.size() == 0) {
			// 新增个人费率
			for (BrandRate brandRate : brandRateList) {
				ChannelRate channelRate = new ChannelRate();
				channelRate.addChannelRate(brandRate, userId, brandId);
				cRateList.add(channelRate);
			}
			channelRateRepository.save(cRateList);
		} else {
			// 更新个人费率
			for (ChannelRate channelRate : channelRateList) {
				long channelId = channelRate.getChannelId();
				short payType = channelRate.getPayType();
				for (BrandRate brandRate : brandRateList) {
					long channelId1 = brandRate.getChannelId();
					Short payType1 = brandRate.getPayType();
					if (channelId == channelId1 && payType == payType1) {
						channelRate.setRate(brandRate.getRate());
						channelRate.setExtraFee(brandRate.getExtraFee());
						channelRate.setGradeRate(brandRate.getGradeRate());
					}
				}
				cRateList.add(channelRate);
			}
			channelRateRepository.save(cRateList);
		}

		// 如果该用户是否注册上游通道，修改上游通道费率
		List<PassageWayRegister> registerList = new ArrayList<>();
		List<PassageWayRegister> passageWayRegisterList = passageWayRegisterRepository.queryByUserId(userId + "");
		if (null != passageWayRegisterList && passageWayRegisterList.size() > 0) {
			// 更新本地注册表费率
			for (PassageWayRegister passageWayRegister : passageWayRegisterList) {
				String channelProductCode = passageWayRegister.getChannelProductCode();
				for (ChannelRate channelRate : cRateList) {
					String channelId = String.valueOf(channelRate.getChannelId());
					if (channelId.equals(channelProductCode)) {
						passageWayRegister.setCreditRate(channelRate.getRate());
					}
				}
				registerList.add(passageWayRegister);
				// 更新上游通道费率
				Map<String, String> resMap = FreeQuickProxyService.modifyMerchantFeeInfo(passageWayRegister.getRequestNo(),
						ChanPay.of(passageWayRegister.getChannelProductCode()).name(), CommonConstants.CREDIT_0, "TRADE", passageWayRegister.getCreditRate().toString(), "");
				String bizCode = resMap.get("bizCode");
				String bizMsg = resMap.get("bizMsg");
				String code = resMap.get("code");
				if (!"1".equals(bizCode) || !"200".equals(code)) {
					// 失败
//					throw new ServiceException(bizMsg);
					LOG.info("后台修改用户等级时修改上游通道费率结果：ChannelProductCode = {}, creditRate = {}, bizMsg = {}", ChanPay.of(passageWayRegister.getChannelProductCode()).name(), passageWayRegister.getCreditRate().toString(), bizMsg);
				}
			}
			passageWayRegisterRepository.save(registerList);
		}
	}
}
